package de.tsajar.es.physics.bullet;

import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.scene.Spatial;
import com.simsilica.es.Entity;
import com.simsilica.es.EntityId;
import com.simsilica.es.EntitySet;
import de.tsajar.es.EntitySystemAppState;
import de.tsajar.es.physics.SolidComponent;
import de.tsajar.es.render.RenderComponent;
import de.tsajar.es.render.RenderSystem;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Eike Foede
 */
public class RigidBodyControlSystem extends EntitySystemAppState {

    EntitySet es;
    RenderSystem rs;
    PhysicsSpace ps;
    private Map<EntityId, PhysicsRigidBody> rigidBodys = new HashMap<EntityId, PhysicsRigidBody>();

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        es = ed.getEntities(SolidComponent.class, RenderComponent.class);
        rs = stateManager.getState(RenderSystem.class);
        ps = stateManager.getState(BulletAppState.class).getPhysicsSpace();
        for (Entity e : es) {
            addEntity(e);
        }
    }

    @Override
    public void update(float tpf) {
        es.applyChanges();
        for (Entity e : es.getAddedEntities()) {
            addEntity(e);
        }
        for (Entity e : es.getRemovedEntities()) {
            removeEntity(e);
        }
    }

    private void addEntity(Entity e) {
        Spatial s = rs.getSpatial(e.getId());
        if (s != null) {
            PhysicsRigidBody prb = new PhysicsRigidBody(CollisionShapeFactory.createMeshShape(s),0);
            rigidBodys.put(e.getId(), prb);
            ps.add(prb);

        } else {
            System.out.println("No spatial for entity, can't create CollisionShape!");
        }
    }

    private void removeEntity(Entity e) {
        PhysicsRigidBody prb = rigidBodys.get(e.getId());
        if (prb != null) {
            ps.remove(prb);
        } else {
            System.out.println("ERROR!");
        }
        rigidBodys.remove(e.getId());
    }
}
